#pragma once

namespace AVUI {

class OptimizedTemplateContent : public Object
{
    friend class XamlParser;
public:
    DECLARE_ELEMENT(RelativeSource, Object);

    OptimizedTemplateContent(FrameworkTemplate* pTemplate) : m_pTemplate(pTemplate), m_stackDepth(0), m_currentStreamPos(0) { };

    ObjectPtr LoadOptimizedTemplateContent(DependencyObject* pTemplatedParent);

    const Type* GetTypeFromChildName(const String& name);
    bool get_IsEmpty() { return m_templateStream.get_Count() == 0; }

private:

    void UpdateChildren(DependencyObject* pTemplatedParent);
    void RecordStartElement(const WCHAR* pwchElement, int cchElement);
    bool RecordEndElement();
    void RecordCharacters(const WCHAR* pwchCharacters, int cchElement);
    void RecordBeginAttributes();
    void RecordAttribute(const WCHAR* pwchName, int cchName, const WCHAR* pwchValue, int cchValue);
    void RecordEndAttributes();
    void RecordTemplateChild(const String& childName, const Type* pChildType);
    void RecordTemplateChildInstance(DependencyObject* pDOTemplateCreator, DependencyObject* pDO);

    struct ChildNameLookup
    {
        ChildNameLookup() : pType(NULL) { }
        ChildNameLookup(String* pString, const Type* pTypeIn) : pType(pTypeIn), ChildName(pString) { }

        TRefCountedPtr<String> ChildName;
        const Type* pType;
    };

    enum StreamTag
    {
        StreamTagStartElement,
        StreamTagEndElement,
        StreamTagCharacters,
        StreamTagBeginAttributes,
        StreamTagAttribute,
        StreamTagEndAttributes,
    };

    void WriteStreamTag(StreamTag streamTag);
    void WriteStreamString(const WCHAR* pwch, int cch);

    bool ReadNextStreamTag(StreamTag* pStreamTag);
    bool ReadNextStreamString(const WCHAR** ppwchData, int* pcchData);

    void WriteDataToStream(const void* pvData, int cbData);
    void ReadDataFromStream(void* pvData, int cbData);
    void BeginReadStream();

    ItemStructList<ChildNameLookup> ChildNameToIndex;
    TRefCountedPtr<ItemStructList<TRefCountedPtr<DependencyObject> > > m_pChildInstances;
    ItemStructList<unsigned char> m_templateStream;

    int m_stackDepth;
    int m_currentStreamPos;
    FrameworkTemplate* m_pTemplate;
};


}; // End namespace AVUI

